﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Acsys.Entity;
using System.Collections;

namespace Acsys
{
    public partial class CreditTransactionForm : Form, IChildForm
    {
        CreditTransaction m_crTransaction = new CreditTransaction();
        IMainForm m_mainForm;
        bool m_enable = false;

        public CreditTransactionForm(Form parent, string name)
        {
            InitializeComponent();
            InitializeButtonClick();
            this.Name = name;
            this.MdiParent = parent;
            m_mainForm = (IMainForm)parent;
            loadComboDataSource();
            loadRecords();
            //ClearForm();
            //setEditMode(EditMode.New);
            dataGridViewPayment.CellValidating += new DataGridViewCellValidatingEventHandler(dataGridViewPayment_CellValidating);
            dataGridViewPayment.CellValidated += new DataGridViewCellEventHandler(dataGridViewPayment_CellValidated);
            dataGridViewPayment.RowsAdded += new DataGridViewRowsAddedEventHandler(dataGridViewPayment_RowsAdded);
            if (listView1.Items.Count > 0)
            {
                listView1.Focus();
                listView1.Items[0].Selected = true;
            }
            else
                Clear(null, null);
        }
        void dataGridViewPayment_RowsAdded(object sender, DataGridViewRowsAddedEventArgs e)
        {
            if (!m_enable) return;
            dataGridViewPayment[ColumnCcy.Index, e.RowIndex].Value = ColumnCcy.Items[0];
            dataGridViewPayment[ColumnDocumentType.Index, e.RowIndex].Value = ColumnDocumentType.Items[0];
            dataGridViewPayment[ColumnDocDate.Index, e.RowIndex].Value = DateTime.Today.ToString("dd-MM-yyyy");
        }

        void dataGridViewPayment_CellValidated(object sender, DataGridViewCellEventArgs e)
        {
            if (e.ColumnIndex == ColumnDocDate.Index)
            {
                DateTime dt = Convert.ToDateTime(dataGridViewPayment[e.ColumnIndex, e.RowIndex].Value);
                dataGridViewPayment[e.ColumnIndex, e.RowIndex].Value = dt.ToString("dd-MM-yyyy");
            }
            if (e.ColumnIndex == ColumnAmount.Index)
            {
                Double amount = Convert.ToDouble(dataGridViewPayment[e.ColumnIndex, e.RowIndex].Value);
                amount = Math.Round(amount, 2);
                dataGridViewPayment[e.ColumnIndex, e.RowIndex].Value = amount;
            }
            CalculateTotalPayment();
        }

        private void CalculateTotalPayment()
        {
            if (!m_enable) return;
            double totalPayment = 0d;
            foreach (DataGridViewRow row in dataGridViewPayment.Rows)
            {
                double paidAMOUNT = Convert.ToDouble(dataGridViewPayment[ColumnAmount.Index, row.Index].Value);
                Currency paidCURRENCY = (Currency)Tools.GetValue((IList)comboBoxCurrency.DataSource, dataGridViewPayment[ColumnCcy.Index, row.Index].Value.ToString());
                Currency debitCurrency = (Currency)comboBoxCurrency.SelectedItem;
                if (paidAMOUNT == 0) continue;
                if (paidCURRENCY == null) continue;
                if (debitCurrency == null) continue;
                totalPayment += (paidAMOUNT * paidCURRENCY.RATE_TO_BASE / debitCurrency.RATE_TO_BASE);
            }
            numericUpDownTotalPayment.Value = Convert.ToDecimal(totalPayment);
        }

        void dataGridViewPayment_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
        {
            dataGridViewPayment.Rows[e.RowIndex].ErrorText = "";
            if (e.ColumnIndex == ColumnDocDate.Index)
            {
                try
                {
                    DateTime date = Convert.ToDateTime(e.FormattedValue);
                }
                catch (Exception x)
                {
                    e.Cancel = true;
                    dataGridViewPayment.Rows[e.RowIndex].ErrorText = x.Message;
                }
            }
            if (e.ColumnIndex == ColumnAmount.Index)
            {
                try
                {
                    Double amount = Convert.ToDouble(e.FormattedValue);
                }
                catch (Exception x)
                {
                    e.Cancel = true;
                    dataGridViewPayment.Rows[e.RowIndex].ErrorText = x.Message;
                }
            }
        }
        private void loadComboDataSource()
        {
            comboBoxCreditType.DataSource = RepositoryFactory.GetInstance().CodeNameRepository().GetAll(new CreditType());
            comboBoxCurrency.DataSource = RepositoryFactory.GetInstance().CodeNameRepository().GetAll(new Currency());
            comboBoxVessel.DataSource = RepositoryFactory.GetInstance().CodeNameRepository().GetAll(new Vessel());
            comboBoxTOP.DataSource = RepositoryFactory.GetInstance().CodeNameRepository().GetAll(new TermOfPayment());
            comboBoxPaymentStatus.DataSource = Enum.GetNames(typeof(PaymentStatus));
            ColumnCcy.DataSource = Tools.GetString(RepositoryFactory.GetInstance().CodeNameRepository().GetAll(new Currency()));
            ColumnDocumentType.DataSource = Enum.GetNames(typeof(DocumentType));
        }

        private void InitializeButtonClick()
        {
            toolStripButtonSave.Click += new EventHandler(Save);
            toolStripButtonEdit.Click += new EventHandler(Edit);
            toolStripButtonDelete.Click += new EventHandler(Delete);
            toolStripButtonClear.Click += new EventHandler(Clear);
        }
        private void setEditMode(EditMode editmode)
        {
            toolStripButtonSave.Enabled = (editmode == EditMode.New || editmode == EditMode.Update) && m_mainForm.CurrentUser.FORM_CRTR_SAVE;
            toolStripButtonEdit.Enabled = (editmode == EditMode.View) && m_mainForm.CurrentUser.FORM_CRTR_SAVE;
            toolStripButtonDelete.Enabled = (editmode == EditMode.View) && m_mainForm.CurrentUser.FORM_CRTR_DELETE;
            toolStripButtonClear.Enabled = m_mainForm.CurrentUser.FORM_CRTR_SAVE;
            ReloadMainFormButton();
        }
        private void ReloadMainFormButton()
        {
            m_mainForm.EnableButtonSave(toolStripButtonSave.Enabled);
            m_mainForm.EnableButtonEdit(toolStripButtonEdit.Enabled);
            m_mainForm.EnableButtonDelete(toolStripButtonDelete.Enabled);
            m_mainForm.EnableButtonClear(m_mainForm.CurrentUser.FORM_DT_SAVE);
        }
        private void loadRecords()
        {
            try
            {
                this.Cursor = Cursors.WaitCursor;
                listView1.Items.Clear();
                IList records = RepositoryFactory.GetInstance().CodeNameRepository().GetAll(m_crTransaction);
                foreach (CreditTransaction d in records)
                {
                    ListViewItem item = listView1.Items.Add(d.TRANSACTION_DATE.ToString("dd-MM-yyyy"));
                    item.SubItems.Add(d.CODE);
                    item.SubItems.Add(RepositoryFactory.GetInstance().CodeNameRepository().GetById(d.CREDIT_TYPE).ToString());
                    item.SubItems.Add(d.DESCRIPTION);
                    item.SubItems.Add(RepositoryFactory.GetInstance().CodeNameRepository().GetById(d.CURRENCY).ToString());
                    item.SubItems.Add(d.AMOUNT.ToString(Tools.CreateFormat(2)));
                    item.SubItems.Add(d.PAYMENTSTATUS.ToString());
                    item.Tag = d;
                }
                this.Cursor = Cursors.Default;
            }
            catch (Exception x)
            {
                MessageBox.Show(x.Message, "Message", MessageBoxButtons.OK, MessageBoxIcon.Information);
                this.Cursor = Cursors.Default;
            }
        }
        public void ClearForm()
        {
            try
            {
                textBoxCode.Text = "";//"ACC" + (RepositoryFactory.GetInstance().UserRepository().GetMaximumID(m_crTransaction) + 1).ToString().PadLeft(3, '0');
                textBoxDesc.Text = "";
                dateTimePickerDate.Value = DateTime.Today;
                comboBoxCreditType.SelectedIndex = 0;
                comboBoxCurrency.SelectedIndex = 0;
                comboBoxVessel.Text = "";
                comboBoxTOP.SelectedIndex = 0;
                numericUpDownAmount.Value = 0m;
                comboBoxPaymentStatus.SelectedIndex = 0;
                m_crTransaction = new CreditTransaction();
                dataGridViewPayment.Rows.Clear();
                numericUpDownTotalPayment.Value = 0;
                errorProvider1.Clear();              
            }
            catch (Exception x)
            {
                MessageBox.Show(x.Message, "Message", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }
        public void Save(object sender, EventArgs e)
        {
            try
            {
                if (Valid())
                {
                    this.Cursor = Cursors.WaitCursor;
                    UpdateEntity();
                    if (m_crTransaction.ID == 0)
                    {
                        RepositoryFactory.GetInstance().CreditTransactionRepository().Save(m_crTransaction);
                    }
                    else
                    {
                        RepositoryFactory.GetInstance().CreditTransactionRepository().Update(m_crTransaction);
                    }
                    MessageBox.Show("Record has been saved");
                    ClearForm();
                    loadRecords();
                    textBoxCode.Focus();
                    this.Cursor = Cursors.Default;
                }
            }
            catch (Exception x)
            {
                MessageBox.Show(x.Message, "Message", MessageBoxButtons.OK, MessageBoxIcon.Information);
                this.Cursor = Cursors.Default;
            }
        }
        private void UpdateEntity()
        {
            m_crTransaction.CODE = textBoxCode.Text.Trim();
            m_crTransaction.DESCRIPTION = textBoxDesc.Text.Trim();
            m_crTransaction.TRANSACTION_DATE = dateTimePickerDate.Value;
            m_crTransaction.CREDIT_TYPE = (CreditType)comboBoxCreditType.SelectedItem;
            m_crTransaction.CURRENCY = (Currency)comboBoxCurrency.SelectedItem;
            m_crTransaction.TERM_OF_PAYMENT = (TermOfPayment)comboBoxTOP.SelectedItem;
            m_crTransaction.VESSEL = (Vessel)comboBoxVessel.SelectedItem;
            m_crTransaction.AMOUNT = Convert.ToDouble(numericUpDownAmount.Value);
            //m_crTransaction.PAYMENTSTATUS = (PaymentStatus)Enum.Parse(typeof(PaymentStatus), comboBoxPaymentStatus.SelectedItem.ToString());
            m_crTransaction.PAYMENT_LIST.Clear();
            CalculateTotalPayment();
            double totalPayment = Convert.ToDouble(numericUpDownTotalPayment.Value);
            foreach (DataGridViewRow row in dataGridViewPayment.Rows)
            {
                PaymentCreditTransaction pyd = new PaymentCreditTransaction();
                pyd.AMOUNT = Convert.ToDouble(dataGridViewPayment[ColumnAmount.Index, row.Index].Value);
                pyd.BANK = dataGridViewPayment[ColumnBank.Index, row.Index].Value == null ? "" : dataGridViewPayment[ColumnBank.Index, row.Index].Value.ToString();
                pyd.CODE = dataGridViewPayment[ColumnDocNo.Index, row.Index].Value == null ? "" : dataGridViewPayment[ColumnDocNo.Index, row.Index].Value.ToString();
                pyd.CURRENCY = (Currency)Tools.GetValue((IList)comboBoxCurrency.DataSource, dataGridViewPayment[ColumnCcy.Index, row.Index].Value.ToString());
                pyd.CREDIT_TRANSACTION = m_crTransaction;
                pyd.DOCUMENT_TYPE = (DocumentType)Enum.Parse(typeof(DocumentType), dataGridViewPayment[ColumnDocumentType.Index, row.Index].Value.ToString());
                if (pyd.AMOUNT == 0) continue;
                m_crTransaction.PAYMENT_LIST.Add(pyd);
                //if (m_crTransaction.CURRENCY.ID == pyd.CURRENCY.ID)
                //totalPayment += (pyd.AMOUNT * pyd.CURRENCY.RATE_TO_BASE / m_crTransaction.CURRENCY.RATE_TO_BASE);
            }
            m_crTransaction.OUTSTANDING_AMOUNT = m_crTransaction.AMOUNT - totalPayment;
            m_crTransaction.PAYMENTSTATUS = m_crTransaction.OUTSTANDING_AMOUNT <= 0 ? PaymentStatus.Close :
                (m_crTransaction.OUTSTANDING_AMOUNT > 0) && (m_crTransaction.OUTSTANDING_AMOUNT < m_crTransaction.AMOUNT) ? PaymentStatus.OutStanding :
                PaymentStatus.Open;
            m_crTransaction.TOTAL_PAYMENT_AMOUNT = totalPayment;
        }
        public bool Valid()
        {
            bool a = textBoxCode.Text == "";
            bool b = textBoxDesc.Text == "";
            bool c = comboBoxCreditType.SelectedItem == null;
            bool d = comboBoxCurrency.SelectedItem == null;
            bool e = comboBoxVessel.SelectedItem == null;
            bool f = comboBoxTOP.SelectedItem == null;


            if (a) errorProvider1.SetError(textBoxCode, "Code can not Empty");
            if (b) errorProvider1.SetError(textBoxDesc, "Description can not Empty");
            if (c) errorProvider1.SetError(comboBoxCreditType, "Credit Type can not Empty");
            if (d) errorProvider1.SetError(comboBoxCreditType, "Currency can not Empty");
            if (f) errorProvider1.SetError(comboBoxTOP, "TOP can not Empty");
             if (e) errorProvider1.SetError(comboBoxVessel, "Vessel / Vendor can not Empty");

             return !a && !b && !c && !d && !e && !f;
        }
        public void Edit(object sender, EventArgs e)
        {
            setEnableForm(true);
            setEditMode(EditMode.Update);
        }
        public void setEnableForm(bool enable)
        {
            textBoxCode.ReadOnly = !enable;
            textBoxDesc.ReadOnly = !enable;
            dateTimePickerDate.Enabled = enable;
            comboBoxCreditType.Enabled = enable;
            comboBoxCurrency.Enabled = enable;
            numericUpDownAmount.Enabled = enable;
            comboBoxTOP.Enabled = enable;
            comboBoxVessel.Enabled = enable;
            //comboBoxPaymentStatus.Enabled = enable;
            ColumnCcy.ReadOnly = !enable;
            ColumnAmount.ReadOnly = !enable;
            ColumnDocNo.ReadOnly = !enable;
            ColumnDocumentType.ReadOnly = !enable;
            ColumnDocDate.ReadOnly = !enable;
            ColumnBank.ReadOnly = !enable;
            m_enable = enable;
            dataGridViewPayment.AllowUserToAddRows = enable;
        }
        public void Delete(object obj, EventArgs e)
        {
            try
            {
                if (m_crTransaction.ID > 0)
                {
                    this.Cursor = Cursors.WaitCursor;
                    if (MessageBox.Show("Please confirm to delete", "Confirmation", MessageBoxButtons.YesNo, MessageBoxIcon.Information) == DialogResult.No) { this.Cursor = Cursors.Default; return; }
                    RepositoryFactory.GetInstance().CreditTransactionRepository().Delete(m_crTransaction);
                    removeRecord(m_crTransaction.ID);
                    ClearForm();
                    setEnableForm(true);
                    setEditMode(EditMode.New);
                    this.Cursor = Cursors.Default;
                }

            }
            catch (Exception x)
            {
                MessageBox.Show(x.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Information);
                this.Cursor = Cursors.Default;
            }
        }
        private void removeRecord(int id)
        {
            foreach (ListViewItem item in listView1.Items)
            {
                CreditTransaction dep = (CreditTransaction)item.Tag;
                if (dep.ID == id)
                {
                    listView1.Items.Remove(item);
                    break;
                }
            }
        }
        public void Clear(object sender, EventArgs e)
        {
            ClearForm();
            setEnableForm(true);
            setEditMode(EditMode.New);
            textBoxCode.Focus();
        }

        private void listView1_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (listView1.SelectedItems.Count == 0) return;
            ClearForm();
            m_crTransaction = (CreditTransaction)listView1.SelectedItems[0].Tag;
            m_enable = false;
            loadData();
            setEnableForm(false);
            setEditMode(EditMode.View);
        }
        private void loadData()
        {
            if (m_crTransaction.ID == 0) return;
            textBoxCode.Text = m_crTransaction.CODE;
            textBoxDesc.Text = m_crTransaction.DESCRIPTION;
            dateTimePickerDate.Value = m_crTransaction.TRANSACTION_DATE;
            comboBoxCreditType.Text = RepositoryFactory.GetInstance().CodeNameRepository().GetById(m_crTransaction.CREDIT_TYPE).ToString();
            comboBoxCurrency.Text = RepositoryFactory.GetInstance().CodeNameRepository().GetById(m_crTransaction.CURRENCY).ToString();
            Vessel v = (Vessel)RepositoryFactory.GetInstance().CodeNameRepository().GetById(m_crTransaction.VESSEL);
            comboBoxVessel.Text = v == null ? "" : v.ToString();
            numericUpDownAmount.Value = Convert.ToDecimal(m_crTransaction.AMOUNT);
            comboBoxTOP.Text = m_crTransaction.TERM_OF_PAYMENT.ID == 0 ? "" : RepositoryFactory.GetInstance().CodeNameRepository().GetById(m_crTransaction.TERM_OF_PAYMENT).ToString();
            comboBoxPaymentStatus.Text = m_crTransaction.PAYMENTSTATUS.ToString();
            numericUpDownTotalPayment.Value = Convert.ToDecimal(m_crTransaction.TOTAL_PAYMENT_AMOUNT);
            m_crTransaction.PAYMENT_LIST = RepositoryFactory.GetInstance().CreditTransactionRepository().GetPaymentList(m_crTransaction.ID);
            foreach (PaymentCreditTransaction pyd in m_crTransaction.PAYMENT_LIST)
            {
                pyd.CURRENCY = (Currency)RepositoryFactory.GetInstance().CodeNameRepository().GetById(pyd.CURRENCY);
                dataGridViewPayment.Rows.Add(pyd.CURRENCY.ToString(), pyd.AMOUNT, pyd.DOCUMENT_TYPE.ToString(), pyd.CODE,
                    pyd.TRANSACTION_DATE.ToString("dd-MM-yyyy"), pyd.BANK);
            }
        }
        private void CreditTransactionForm_Activated(object sender, EventArgs e)
        {
            ReloadMainFormButton();
        }

        public void Refresh(object sender, EventArgs e)
        {
            loadComboDataSource();
            loadRecords(); 
            loadData();
        }
        private void PrintPreview(object sender, EventArgs e)
        {
            if (m_crTransaction == null) return;
            DataSet ds = RepositoryFactory.GetInstance().CrTrReportRepository().GetPrintDataSet(m_crTransaction.ID);
            PrintPreviewForm pv = new PrintPreviewForm("CrTrPrint.rdlc", "crTransactionReport_DataTable1", ds);
            pv.ShowDialog();
        }

        private void Print(object sender, EventArgs e)
        {
            if (m_crTransaction == null) return;
            DataSet ds = RepositoryFactory.GetInstance().CrTrReportRepository().GetPrintDataSet(m_crTransaction.ID);
            string deviceInfo =
                             @"<DeviceInfo>
                            <OutputFormat>EMF</OutputFormat>
                            <PageWidth>8.5in</PageWidth>
                            <PageHeight>11in</PageHeight>
                            <MarginTop>0.25in</MarginTop>
                            <MarginLeft>0.25in</MarginLeft>
                            <MarginRight>0.25in</MarginRight>
                            <MarginBottom>0.25in</MarginBottom>
                        </DeviceInfo>";
            DirectPrint dp = new DirectPrint(ds, "CrTrPrint.rdlc", deviceInfo, "crTransactionReport_DataTable1");
            dp.Print();
        }

        private void comboBoxTOP_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (comboBoxTOP.SelectedItem == null) return;
            TermOfPayment top = (TermOfPayment)comboBoxTOP.SelectedItem;
            dateTimePickerEstDate.Value = dateTimePickerDate.Value.AddDays(top.DAY);
        }

        private void dateTimePickerDate_Validated(object sender, EventArgs e)
        {
            if (comboBoxTOP.SelectedItem == null) return;
            TermOfPayment top = (TermOfPayment)comboBoxTOP.SelectedItem;
            dateTimePickerEstDate.Value = dateTimePickerDate.Value.AddDays(top.DAY);
        }
 
        private void toolStripTextBoxSearch_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                try
                {
                    this.Cursor = Cursors.WaitCursor;
                    listView1.Items.Clear();
                    IList records = RepositoryFactory.GetInstance().CreditTransactionRepository().SearchBy(toolStripTextBoxSearch.Text);
                    foreach (CreditTransaction d in records)
                    {
                        ListViewItem item = listView1.Items.Add(d.TRANSACTION_DATE.ToString("dd-MM-yyyy"));
                        item.SubItems.Add(d.CODE);
                        item.SubItems.Add(RepositoryFactory.GetInstance().CodeNameRepository().GetById(d.CREDIT_TYPE).ToString());
                        item.SubItems.Add(d.DESCRIPTION);
                        item.SubItems.Add(RepositoryFactory.GetInstance().CodeNameRepository().GetById(d.CURRENCY).ToString());
                        item.SubItems.Add(d.AMOUNT.ToString(Tools.CreateFormat(2)));
                        item.SubItems.Add(d.PAYMENTSTATUS.ToString());
                        item.Tag = d;
                    }
                    this.Cursor = Cursors.Default;
                }
                catch (Exception x)
                {
                    MessageBox.Show(x.Message, "Message", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    this.Cursor = Cursors.Default;
                }
            }
        }

        private void toolStripButtonSearch_Click(object sender, EventArgs e)
        {
            try
            {
                this.Cursor = Cursors.WaitCursor;
                listView1.Items.Clear();
                IList records = RepositoryFactory.GetInstance().CreditTransactionRepository().SearchBy(toolStripTextBoxSearch.Text);
                foreach (CreditTransaction d in records)
                {
                    ListViewItem item = listView1.Items.Add(d.TRANSACTION_DATE.ToString("dd-MM-yyyy"));
                    item.SubItems.Add(d.CODE);
                    item.SubItems.Add(RepositoryFactory.GetInstance().CodeNameRepository().GetById(d.CREDIT_TYPE).ToString());
                    item.SubItems.Add(d.DESCRIPTION);
                    item.SubItems.Add(RepositoryFactory.GetInstance().CodeNameRepository().GetById(d.CURRENCY).ToString());
                    item.SubItems.Add(d.AMOUNT.ToString(Tools.CreateFormat(2)));
                    item.SubItems.Add(d.PAYMENTSTATUS.ToString());
                    item.Tag = d;
                }
                this.Cursor = Cursors.Default;
            }
            catch (Exception x)
            {
                MessageBox.Show(x.Message, "Message", MessageBoxButtons.OK, MessageBoxIcon.Information);
                this.Cursor = Cursors.Default;
            }
        }

        private void comboBoxCurrency_SelectedIndexChanged(object sender, EventArgs e)
        {
            totalCCYlabel.Text = comboBoxCurrency.SelectedItem == null ? "" : comboBoxCurrency.SelectedItem.ToString();
            if (!m_enable) return;
            CalculateTotalPayment();
        }

        int sortColumn = 0;
        private void listView1_ColumnClick(object sender, ColumnClickEventArgs e)
        {
            if (e.Column != sortColumn)
            {
                sortColumn = e.Column;
                listView1.Sorting = System.Windows.Forms.SortOrder.Ascending;
            }
            else
            {
                if (listView1.Sorting == System.Windows.Forms.SortOrder.Ascending)
                    listView1.Sorting = System.Windows.Forms.SortOrder.Descending;
                else
                    listView1.Sorting = System.Windows.Forms.SortOrder.Ascending;
            }
            this.listView1.ListViewItemSorter = new ListViewItemComparerAscDesc(e.Column);
            listView1.Sort();
            sortColumn = e.Column;
        }
    }
}
